/**
 * Licensed to Open-Ones Group under one or more contributor license
 * agreements. See the NOTICE file distributed with this work
 * for additional information regarding copyright ownership.
 * Open-Ones Group licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a
 * copy of the License at:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package openones.ipresenter.android.blo;

import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;

import openones.ipresenter.android.dao.ConnectionData;
import openones.ipresenter.android.view.PresentActivity;

import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.widget.Toast;

/**
 * Used to get Socket and send message.
 * @author OOG member
 */
public class ConnectionSupport {
    /**
     * The type "int" has 4 bytes.
     */
    private static final int NUM_BYTES_IN_INT = 4;
    
    /**
     * The current connection type (Bluetooth, Wifi).
     */
    private int mConnectionType;
    
    /**
    * Used to get the OutputStream for Bluetooth.
    */
    private BluetoothSocket mBluetoothSocket;
    
    /**
     * Used to get the OutputStream for Wifi.
     */
    private Socket mWifiSocket;
    
    /**
     * Used to send data.
     */
    private OutputStream mOutputStream;
    
   /**
    * constructor.
    */
    public ConnectionSupport() {
        mBluetoothSocket = null;
        mWifiSocket = null;
        mOutputStream = null;
        
    }
    
    /**
     * Setup connection support instance.
     * Get Socket according to the connection type.
     * @param context PresentActivity.
     * @param aConnectionType Connection type.
     * @return True if 
     */
    public boolean setup(Context context, int aConnectionType) {
        mConnectionType = aConnectionType;
        boolean result = true;
       
        ConnectionData connectionData = ((ConnectionData) context.getApplicationContext());
        if (connectionData == null) {
            result = false;
            Toast.makeText(context, "Connection data is empty", Toast.LENGTH_SHORT).show();
            return result;
        }
        
        switch (aConnectionType) {
        case PresentActivity.CONNECTION_TYPE_BLUETOOTH:
            mBluetoothSocket = connectionData.getBluetoothSocket();
            if (mBluetoothSocket == null) {
                result = false;
                Toast.makeText(context, "Get Bluetooth Socket fails", Toast.LENGTH_SHORT).show();
                break;
            }

            try {
                mOutputStream = mBluetoothSocket.getOutputStream();
            } catch (IOException e) {
                mOutputStream = null;
                result = false;
                Toast.makeText(context, "Get Output Stream fails", Toast.LENGTH_SHORT).show();
                e.printStackTrace();
            }
            break;
        case PresentActivity.CONNECTION_TYPE_WIFI:
            mWifiSocket = connectionData.getWifiSocket();
            if (mWifiSocket == null) {
                result = false;
                Toast.makeText(context, "Get Wifi Socket fails", Toast.LENGTH_SHORT).show();
                break;
            }
            
            try {
                mOutputStream = mWifiSocket.getOutputStream();
            } catch (IOException e) {
                mOutputStream = null;
                result = false;
                Toast.makeText(context, "Get Output Stream fails", Toast.LENGTH_SHORT).show();

            }
            break;
            default:
                result = false;
                break;
        } 
        
        return result;
    }
    
    /**
     * Send command via the OutputStream.
     * @param context PresentActivity.
     * @param command Command int.
     * @return True if the command is sent successfully.
     */
    public boolean send (Context context,int command){
  	  boolean result = true;
        if (mOutputStream != null) {
                try {
                    switch (mConnectionType) {
                    case PresentActivity.CONNECTION_TYPE_BLUETOOTH:
                       mOutputStream.write(command);
                        break;
                    case PresentActivity.CONNECTION_TYPE_WIFI:
                        mOutputStream.write(command);
                        break;
                    default:
                        break;
                    }
                    
                } catch (IOException e) {
                    result = false;
                    Toast.makeText(context, "Send command fails", Toast.LENGTH_SHORT).show();
                }
        } else {
            result = false;
        }
        return result;
  }
    /**
     * Send command via the OutputStream.
     * @param context PresentActivity.
     * @param command Command string.
     * @return True if the command is sent successfully.
     */
    public boolean send(Context context, String command) {
        boolean result = true;
        
        if (mOutputStream != null) {
            int dataSize = 0;
            byte[] size = new byte[NUM_BYTES_IN_INT];
            byte[] temp;
            byte[] data;
            
            try {
                data = command.getBytes("US-ASCII");
                dataSize = data.length;
                temp = (dataSize + "").getBytes("US-ASCII");
                
                for (int i = 0; i < NUM_BYTES_IN_INT; i++) {
                    size[i] = 0;
                }
                
                for (int i = 0; i < temp.length; i++) {
                    size[i] = temp[i];
                }
                
                try {
                    switch (mConnectionType) {
                    case PresentActivity.CONNECTION_TYPE_BLUETOOTH:
                        mOutputStream.write((byte) dataSize);
                        mOutputStream.write(data, 0, dataSize);
                        break;
                    case PresentActivity.CONNECTION_TYPE_WIFI:
                        mOutputStream.write(size, 0, NUM_BYTES_IN_INT);
                        mOutputStream.write(data, 0, dataSize);
                        break;
                    default:
                        break;
                    }
                    
                } catch (IOException e) {
                    result = false;
                    Toast.makeText(context, "Send command fails", Toast.LENGTH_SHORT).show();
                }
                
            } catch (UnsupportedEncodingException e1) {
                result = false;
                Toast.makeText(context, "Send command fails", Toast.LENGTH_SHORT).show();
            }
            
        } else {
            result = false;
        }
  
        return result;
    }
    
    /**
     * Free resource.
     * Close the socket and output stream.
     */
    public void freeResource() {
        if (mBluetoothSocket != null) {
            try {
                mBluetoothSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }    
            mBluetoothSocket = null;
        }
        
        if (mWifiSocket != null) {
            try {
                mWifiSocket.close();   
            } catch (IOException e) {
                e.printStackTrace();
            } 
            mWifiSocket = null;
        }
        
        if (mOutputStream != null) {
            try {
                mOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }  
            mOutputStream = null;
        }
    }
    
    /**
     * Check if current connection is still avaliable.
     * @return True if output stream is OK.
     */
    public boolean check() {
        boolean result = true;
        if (mOutputStream == null) {
            result = false;
        }
        
        return result;
    }
    
    
}
